<template>
  <div class="table">
    <c-table-box
      ref="cTableBox"
      index
      checkbox
      auto-height
      hide-func
      :table-height="500"
      :setting="false"
      :data="showTableData"
      :table-span-method="tableSpanMethod"
      :table-config="tableConfig"
      @selection-change="selectionChangeHandle"
    />
  </div>
</template>
<script>
// import Scheme from './Scheme'
const rttf = ['Q014', 'Q015']
import { deepClone } from '@/utils'
const hasPrograms = 'Q014 Q015 Q002 Q003 Q004 Q005 Q019'.split(' ')
export default {
  name: 'Table',
  components: {
    // Scheme
  },
  props: {
    tableData: {
      type: Array,
      default: () => []
    },
    detail: {
      type: Object,
      default: () => ({})
    },
    preview: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      tableConfig: {
        setting: [
          {
            prop: 'areaName',
            label: '所属区域',
            minWidth: 120
          },
          {
            prop: 'spaceName',
            label: '所属空间',
            minWidth: 120
          },
          {
            prop: 'isProgramOutpic',
            label: '是否出图',
            minWidth: 100,
            render: this.switchEditAndText('isProgramOutpic', this.createSwitch, this.createIsOrNotOrText, false, {})
          },
          {
            prop: 'actualOutpicArea',
            label: '出图总面积',
            minWidth: 160,
            render: this.enableEditBy('isProgramOutpic', this.switchEditAndText('actualOutpicArea', this.createNumber, this.createIsOrNotOrText, true, { change: [this.syncValue('actualOutpicArea', '_groupSpace')] }))
          },
          {
            prop: 'outpicDesc',
            label: '出图说明',
            minWidth: 200,
            render: this.enableEditBy('isProgramOutpic', this.switchEditAndText('outpicDesc', this.createTextInput, this.createIsOrNotOrText, true))
          }
        ]
      },
      selections: [],
      // showTableData: [],
      filtersRaw: [
        // { key: 'enable', value: 1, operator: '=' }
      ],
      addTableData: [],
      rawTableData: []
    }
  },
  computed: {
    showTableData() {
      return this.handleData([...this.rawTableData, ...this.addTableData])
    }
  },
  watch: {
    tableData: {
      handler(v) {
        this.rawTableData = deepClone(v).map(e => {
          e.areaName = '门头'
          if ((e.spaceName === '' || e.spaceName === undefined) && (e.styleName !== '' && e.styleName !== undefined)) {
            e.spaceName = e.styleName
            e.styleName = ''
          }
          return e
        })
      },
      immediate: true
    }
  },
  methods: {
    spaceEditable(row) {
      return !rttf.includes(row.areaCode)
    },
    // 条件编辑
    enableEditBy(key, fun) {
      return (h, row) => {
        const t = row[key]
        if (t === '1' || t === 1 || this.preview) {
          return fun(h, row)
        }
        return h('span', '')
      }
    },
    // 可编辑与不可编辑
    switchEditAndText(key, editFun, textFun, isText, on) {
      return (h, row) => {
        if (!this.preview) {
          return editFun(key, on)(h, row)
        } else {
          return textFun(key, isText)(h, row)
        }
      }
    },
    // 是否
    createIsOrNotOrText(key, isText) {
      return (h, row) => {
        const v = row[key]
        if (!isText) {
          const text = (v === 1 || v === '1') ? '是' : '否'
          return h('span', text)
        } else {
          return h('span', v)
        }
      }
    },
    // switch
    createSwitch(key, on = {}) {
      on = { ...(on || {}) }
      const input = on.input
      delete on.input
      return (h, row) => {
        const _on = this.wrapHandle(on, row)
        const v = String(row[key] || 0)
        return h('el-switch', {
          props: {
            activeValue: '1',
            inactiveValue: '0',
            value: v
          },
          on: {
            input: v => {
              this.$set(row, key, v)
              this.$set(row, 'isDetailOutpic', v)// 系列是否出图与isProgramOutpic同值
              if (input instanceof Function) {
                input.call(this, v)
              }
            },
            ..._on
          },
          nativeOn: {
            click: e => {
              e.stopPropagation && e.stopPropagation()
              return false
            }
          }
        })
      }
    },
    // number
    createNumber(key, on = {}) {
      on = { ...(on || {}) }
      const input = on.input
      delete on.input
      return (h, row) => {
        const _on = this.wrapHandle(on, row)
        const v = row[key]
        return h('c-input-number', {
          props: {
            float: true,
            value: v
          },
          on: {
            input: v => {
              this.$set(row, key, v)
              if (input instanceof Function) {
                input.call(this, v)
              }
            },
            ..._on
          },
          nativeOn: {
            click: e => {
              e.stopPropagation && e.stopPropagation()
              return false
            }
          }
        })
      }
    },
    // input
    createTextInput(key, on = {}) {
      on = { ...(on || {}) }
      const input = on.input
      delete on.input
      return (h, row) => {
        const _on = this.wrapHandle(on, row)
        const v = row[key]
        return h('el-input', {
          props: {
            value: v,
            type: 'textarea',
            autosize: { minRow: 1 }
          },
          attrs: {
            maxlength: 1024,
            showWordLimit: true
          },
          on: {
            input: v => {
              this.$set(row, key, v)
              if (input instanceof Function) {
                input.call(this, v)
              }
            },
            ..._on
          },
          nativeOn: {
            click: e => {
              e.stopPropagation && e.stopPropagation()
              return false
            }
          }
        })
      }
    },
    // 处理事件
    wrapHandle(on = {}, ..._args) {
      const t = {}
      Object.entries(on).forEach(function([event, handler]) {
        if (!(handler instanceof Array)) {
          handler = [handler]
        }
        t[event] = function(...args) {
          for (const h of handler) {
            h.call(this, ..._args, ...args)
          }
        }
      })
      return t
    },
    // 同步值
    syncValue(key, groupKey) {
      return (row, v) => {
        // const v = row[key]
        for (const item of row[groupKey] || []) {
          this.$set(item, key, v)
        }
      }
    },
    // 系列报图，出图同步到空间
    syncValueBySome(key, targetKey, groupKey) {
      const fun = this.syncValue(targetKey, groupKey)
      return (row, v) => {
        const group = row[groupKey] || []
        if (v === 1 || v === '1') {
          fun.call(this, row, v)
        } else {
          if (group.some(e => (e[key] === 1 || e[key] === '1'))) {
            fun.call(this, row, '1')
          } else {
            fun.call(this, row, '0')
          }
        }
      }
    },
    // 出图面积汇总
    syncValueSum(key, targetKey, targetGroupKey, getValueGroup) {
      const fun = this.syncValue(targetKey, targetGroupKey)
      return (row, v) => {
        let group
        if (getValueGroup instanceof Function) {
          group = getValueGroup(row, v)
        } else {
          group = row[targetGroupKey] || []
        }
        if (group.length === 0) return
        const value = group.reduce((a, b) => {
          if (typeof a !== 'object') {
            a = { [key]: a }
          }
          let tmp = Number(a[key])
          const a1 = isNaN(tmp) ? 0 : tmp
          tmp = Number(b[key])
          const b1 = isNaN(tmp) ? 0 : tmp
          return a1 + b1
        }, { [key]: 0 })
        fun.call(this, row, value)
      }
    },

    tableSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 区域
      if ([2].includes(columnIndex)) {
        return [row._areaRowSpan, 1]
      }
      if ([3].includes(columnIndex)) {
        return [row._spaceRowSpan, 1]
      }
      return [1, 1]
    },
    // arg = {flag, index, groupKey, span}
    classifyFun(data, args) {
      const classify = {}
      const _args = [...args]
      const { flag, index, groupKey, span } = _args.shift()
      for (const item of data) {
        // 先清理数据，方便二次处理
        Object.keys(item).forEach(key => {
          if (/^_.+/.test(key)) {
            delete item[key]
          }
        })
        const f = item[flag] === undefined ? flag : item[flag]
        // const i = item[index] === undefined ? 0 : item[index]
        // const key = `${f}@@${i}`
        const key = `${f}`
        if (classify[key] === undefined) {
          classify[key] = {
            list: [],
            groupKey: `_${groupKey}`,
            span: `_${span}`,
            index: `_${index}`,
            order: item[index]
          }
        }
        if (classify[key].order === undefined) {
          classify[key].order = item[index]
        }
        classify[key].list.push(item)
      }
      if (_args.length > 0) {
        Object.values(classify).forEach(e => {
          e.classify = this.classifyFun(e.list, _args)
        })
      }
      return classify
    },
    handleData(data) {
      // 7.列表显示顺序：先按区域合并展示，区域相同按空间显示顺序displayOrder正序合并展示，
      // 空间相同按专区显示顺序正序合并展示，专区相同的按系列编码从大到小倒序展示
      // areaCode
      //   @ApiModelProperty("区域顺序")
      //   private Integer areaIndex;
      //   @ApiModelProperty("空间顺序")
      //   private Integer spaceIndex;
      //   @ApiModelProperty("专区顺序")
      //   private Integer styleIndex;
      // 按区域分类
      const args = [
        // { flag: 'picTaskCode', index: 'picTaskCodeIndex', groupKey: 'groupPicTaskCode', span: 'picTaskCodeRowSpan' },
        { flag: 'areaCode', index: 'areaIndex', groupKey: 'groupArea', span: 'areaRowSpan' },
        { flag: 'spaceCode', index: 'spaceIndex', groupKey: 'groupSpace', span: 'spaceRowSpan' }
        // { flag: 'styleName', index: 'styleIndex', groupKey: 'groupStyle', span: 'styleRowSpan' }
      ]
      const area = this.classifyFun(data, args)
      // 排序函数
      const sort = (data, order = 'asc') => {
        const t = Object.entries(data)
        const l = t.length
        for (let i = 0; i < l; i++) {
          for (let m = i + 1; m < l; m++) {
            const a = t[i]
            // let i1 = Number(a[0].split('@@')[1])
            let i1 = Number(a[1].order)
            if (isNaN(i1)) { i1 = 0 }
            const b = t[m]
            // let i2 = Number(b[0].split('@@')[1])
            let i2 = Number(b[1].order)
            if (isNaN(i2)) { i2 = 0 }
            if (order === 'asc' && i1 > i2) {
              t.splice(i, 1, b)
              t.splice(m, 1, a)
            } else if (order === 'desc' && i1 < i2) {
              t.splice(i, 1, b)
              t.splice(m, 1, a)
            }
          }
        }
        return t
      }
      const result = []
      const collectFun = (data) => {
        const arrs = sort(data)
        arrs.forEach(e => {
          const t = e[1]
          // eslint-disable-next-line no-unused-vars
          const { list, classify, groupKey, span } = t
          list.forEach((e, i) => {
            e[groupKey] = list
          })
          if (classify) {
            collectFun(classify)
          } else {
            // 系列
            list.sort((a, b) => {
              const a1 = Number(a.seriesCode || 0)
              const b1 = Number(b.seriesCode || 0)
              return b1 - a1
            })
            result.push(...list)
          }
        })
      }
      collectFun(area)
      result.forEach((e, i) => {
        const merge = (row, flag, span, groupKey) => {
          if (row[flag]) return
          const list = row[groupKey]
          if (row[flag] === undefined) {
            list.forEach(e => {
              e[flag] = true
              e[span] = 0
            })
            row[span] = list.length
          }
        }
        // merge(e, '_picTaskCodeMerge', '_picTaskCodeRowSpan', '_groupPicTaskCode')
        merge(e, '_areaMerge', '_areaRowSpan', '_groupArea')
        merge(e, '_spaceMerge', '_spaceRowSpan', '_groupSpace')
        // merge(e, '_styleMerge', '_styleRowSpan', '_groupStyle')
      })
      return result
    },
    selectionChangeHandle(v) {
      this.selections = v
    },
    // 校验数据
    validate(isPromise = true) {
      const result = []
      const msg = (a, i, b) => {
        const m = typeof i === 'number' ? `${a}第${i + 1}行${b}!` : `${a}${i}${b}!`
        this.$message.warning(m)
        return isPromise ? Promise.reject(m) : false
      }
      for (let i = 0; i < this.showTableData.length; i++) {
        const v = { ...this.showTableData[i] }
        Object.keys(v).forEach(key => {
          if (/^_.+/.test(key)) {
            delete v[key]
          }
        })
        // 若所属区域为“软体”或“成品套房”，则出图面积及配套定制出图面积填到专区维度，是否出图维护到专区+系列维度，方案上的实际出图面积通过专区出图面积自动汇总显示，
        // 不允许修改，当已出图系列有对应配套定制系列时，专区对应配套定制面积必填
        if (this.$isTrue(v.isProgramOutpic, 1, '1')) {
          if (!this.$gtEmpty(v.actualOutpicArea)) {
            return msg('请填写【', v.spaceName, '】出图面积')
          }
        }
        for (const k of 'isDetailOutpic isOutpic isProgramOutpic isReport isReportPic isSeriesReportPic'.split(' ')) {
          if (v[k] === undefined || v[k] === '') {
            v[k] = 0
          }
        }
        result.push(v)
      }
      return isPromise ? Promise.resolve(result) : result
    }
  }
}
</script>
<style lang="scss" scoped>
.table{
  padding-top: 12px;
  & /deep/ .el-table__row{
    background-color: #fff !important;
  }
  & /deep/ .hover-row{
    background-color: #fff !important;
  }
  & /deep/ td{
    background-color: #fff !important;
  }
}
</style>
